home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / src / SimHector / cpu / RegisterTransfer.cxx < prev   
C/C++ Source or Header  |  1995-07-26  |  14KB  |  384 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //   File:        RegisterTransfer.cxx (Part of ControlUnit Class)
  4. //                                                                      
  5. //   Purpose:     This module contains the register transfer functions  
  6. //                for the HECTOR  simulator.  These functions           
  7. //                execute the register transfer operations called by    
  8. //                the instruction execution functions in instexec.c     
  9. //                by setting latches, selecting registers, setting      
  10. //                muxes, and selecting the alu operation.  Also         
  11. //                included are the functions called by the register     
  12. //                transfer functions.  NOTE that none of these          
  13. //                functions actually perform the data path operations,  
  14. //                they simply set up for the Clock() function to do     
  15. //                the data path operation in proper order.  Therefore,  
  16. //                the sequence of instructions in these functions is    
  17. //                arbitrary                                             
  18. //                                                                      
  19. //   Author:      Greg DeHoogh                                         
  20. //
  21. //   Modified:    Bradford W. Mott
  22. //                                                                      
  23. //   Date:        17 February 1990                                      
  24. //                                                                      
  25. //   History:     Spring 1990 -- Creation                               
  26. //
  27. //                December 4,1993 - Modified for use with BSVC
  28. //                                                                      
  29. ///////////////////////////////////////////////////////////////////////////////
  30.  
  31. #include "ControlUnit.hxx"
  32.  
  33. ///////////////////////////////////////////////////////////////////////////////
  34. // reg_a -> reg_b
  35. ///////////////////////////////////////////////////////////////////////////////
  36. const char* ControlUnit::reg_to_reg(int reg_a, int reg_b)
  37. {
  38.    data_path.a_sel(reg_a);
  39.    data_path.b_sel(reg_b);
  40.    data_path.alu_fn(PASS_A_NCC);
  41.    data_path.alu_gt();
  42.    data_path.wrt_b();
  43.    return(data_path.Clock());
  44. }
  45.  
  46. ///////////////////////////////////////////////////////////////////////////////
  47. // (reg_a) -> reg_b
  48. ///////////////////////////////////////////////////////////////////////////////
  49. const char* ControlUnit::reg_indirect_to_reg(int reg_a, int reg_b)
  50. {
  51.    data_path.a_sel(reg_a);
  52.    data_path.b_sel(reg_b);
  53.    data_path.mar_sel(A_BUS);
  54.    data_path.mar_latch();
  55.    data_path.mar_out_en();
  56.    data_path.db_gt();
  57.    data_path.wrt_b();
  58.    return(data_path.Clock());
  59. }
  60.  
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // reg_a -> (reg_b)   
  63. ///////////////////////////////////////////////////////////////////////////////
  64. const char* ControlUnit::reg_to_reg_indirect(int reg_a, int reg_b)
  65. {
  66.    data_path.a_sel(reg_a);
  67.    data_path.b_sel(reg_b);
  68.    data_path.mar_sel(B_BUS);
  69.    data_path.mar_latch();
  70.    data_path.mar_out_en();
  71.    data_path.mdr_sel(A_BUS);
  72.    data_path.mdr_latch();
  73.    data_path.mdr_out_en();
  74.    return(data_path.Clock());
  75. }
  76.  
  77. ///////////////////////////////////////////////////////////////////////////////
  78. // reg -> (mar)   
  79. ///////////////////////////////////////////////////////////////////////////////
  80. const char* ControlUnit::reg_to_mar_indirect(int reg)
  81. {
  82.    data_path.a_sel(reg);
  83.    data_path.mar_out_en();
  84.    data_path.mdr_sel(A_BUS);
  85.    data_path.mdr_latch();
  86.    data_path.mdr_out_en();
  87.    return(data_path.Clock());
  88. }
  89.  
  90. ///////////////////////////////////////////////////////////////////////////////
  91. // (mar) -> reg                                                      
  92. ///////////////////////////////////////////////////////////////////////////////
  93. const char* ControlUnit::mar_indirect_to_reg(int reg)
  94. {
  95.    data_path.a_sel(reg);
  96.    data_path.mar_out_en();
  97.    data_path.db_gt();
  98.    data_path.wrt_a();
  99.    return(data_path.Clock());
  100. }
  101.  
  102. ///////////////////////////////////////////////////////////////////////////////
  103. // mdr -> (mar)                                                      
  104. ///////////////////////////////////////////////////////////////////////////////
  105. const char* ControlUnit::mdr_to_mar_indirect(void)
  106. {
  107.    data_path.mar_out_en();
  108.    data_path.mdr_out_en();
  109.    return(data_path.Clock());
  110. }
  111.  
  112. ///////////////////////////////////////////////////////////////////////////////
  113. // reg + 1 -> reg                                                   
  114. ///////////////////////////////////////////////////////////////////////////////
  115. const char* ControlUnit::inc_reg(int reg)
  116. {
  117.    data_path.a_sel(reg);
  118.    data_path.alu_fn(INC_A_NCC);
  119.    data_path.alu_gt();
  120.    data_path.wrt_a();
  121.    return(data_path.Clock());
  122. }
  123.  
  124. ///////////////////////////////////////////////////////////////////////////////
  125. // reg_a OP reg_b -> reg_b                                            
  126. ///////////////////////////////////////////////////////////////////////////////
  127. const char* ControlUnit::reg_op_reg_to_reg(int reg_a, int reg_b)
  128. {
  129.    int OP = data_path.ir >> 12;
  130.  
  131.    data_path.a_sel(reg_a);
  132.    data_path.b_sel(reg_b);
  133.    data_path.alu_fn((ALUFunction)OP);
  134.    data_path.alu_gt();
  135.    data_path.wrt_b();
  136.    return(data_path.Clock());
  137. }
  138.  
  139. ///////////////////////////////////////////////////////////////////////////////
  140. // reg_a OP reg_b -> mdr                                           
  141. ///////////////////////////////////////////////////////////////////////////////
  142. const char* ControlUnit::reg_op_reg_to_mdr(int reg_a, int reg_b)
  143. {
  144.    int OP = data_path.ir >> 12;
  145.  
  146.    data_path.a_sel(reg_a);
  147.    data_path.b_sel(reg_b);
  148.    data_path.alu_fn((ALUFunction)OP);
  149.    data_path.mdr_sel(ALU_BUS);
  150.    data_path.mdr_latch();
  151.    return(data_path.Clock());
  152. }
  153.  
  154. ///////////////////////////////////////////////////////////////////////////////
  155. // reg_a + reg_b -> reg_b                                          
  156. ///////////////////////////////////////////////////////////////////////////////
  157. const char* ControlUnit::reg_plus_reg_to_reg(int reg_a, int reg_b)
  158. {
  159.    data_path.a_sel(reg_a);
  160.    data_path.b_sel(reg_b);
  161.    data_path.alu_fn(ADD_NCC);
  162.    data_path.alu_gt();
  163.    data_path.wrt_b();
  164.    return(data_path.Clock());
  165. }
  166.  
  167. ///////////////////////////////////////////////////////////////////////////////
  168. // reg_a + reg_b -> mar                                           
  169. ///////////////////////////////////////////////////////////////////////////////
  170. const char* ControlUnit::reg_plus_reg_to_mar(int reg_a, int reg_b)
  171. {
  172.    data_path.a_sel(reg_a);
  173.    data_path.b_sel(reg_b);
  174.    data_path.alu_fn(ADD_NCC);
  175.    data_path.mar_sel(ALU_BUS);
  176.    data_path.mar_latch();
  177.    return(data_path.Clock());
  178. }
  179.  
  180. ///////////////////////////////////////////////////////////////////////////////
  181. // reg - 1 -> reg                             
  182. ///////////////////////////////////////////////////////////////////////////////
  183. const char* ControlUnit::dec_reg(int reg)
  184. {
  185.    data_path.a_sel(reg);
  186.    data_path.alu_fn(DEC_A_NCC);
  187.    data_path.alu_gt();
  188.    data_path.wrt_a();
  189.    return(data_path.Clock());
  190. }
  191.  
  192. ///////////////////////////////////////////////////////////////////////////////
  193. // reg_a OP reg_b        
  194. ///////////////////////////////////////////////////////////////////////////////
  195. const char* ControlUnit::reg_op_reg(int reg_a, int reg_b)
  196. {
  197.    int OP = data_path.ir >> 12;
  198.  
  199.    data_path.a_sel(reg_a);
  200.    data_path.b_sel(reg_b);
  201.    data_path.alu_fn((ALUFunction)OP);
  202.    return(data_path.Clock());
  203. }
  204.  
  205. ///////////////////////////////////////////////////////////////////////////////
  206. // op reg -> reg (op obtained from OP and DM fields)   
  207. ///////////////////////////////////////////////////////////////////////////////
  208. const char* ControlUnit::op_reg_to_reg(int reg)
  209. {
  210.    int OP = data_path.ir >> 12;
  211.    int DM = (data_path.ir & 0x0300) >> 8;
  212.  
  213.    data_path.a_sel(reg);
  214.    data_path.alu_fn((ALUFunction)((OP << 4) | DM));
  215.    data_path.alu_gt();
  216.    data_path.wrt_a();
  217.    return(data_path.Clock());
  218. }
  219.  
  220. ///////////////////////////////////////////////////////////////////////////////
  221. // op reg -> mdr (op obtained from OP and DM fields)    
  222. ///////////////////////////////////////////////////////////////////////////////
  223. const char* ControlUnit::op_reg_to_mdr(int reg)
  224. {
  225.    int OP = data_path.ir >> 12;
  226.    int DM = (data_path.ir & 0x0300) >> 8;
  227.  
  228.    data_path.a_sel(reg);
  229.    data_path.alu_fn((ALUFunction)((OP << 4) | DM));
  230.    data_path.mdr_sel(ALU_BUS);
  231.    data_path.mdr_latch();
  232.    return(data_path.Clock());
  233. }
  234.  
  235. ///////////////////////////////////////////////////////////////////////////////
  236. // swap(reg) -> reg (swaps high byte and low byte)
  237. ///////////////////////////////////////////////////////////////////////////////
  238. const char* ControlUnit::swap_reg_to_reg(int reg_a, int reg_b)
  239. {
  240.    data_path.a_sel(reg_a);
  241.    data_path.b_sel(reg_b);
  242.    data_path.alu_fn(SWAP_A);
  243.    data_path.alu_gt();
  244.    data_path.wrt_b();
  245.    return(data_path.Clock());
  246. }
  247.  
  248. ///////////////////////////////////////////////////////////////////////////////
  249. // swap(reg) -> mdr (swaps high byte and low byte)                  
  250. ///////////////////////////////////////////////////////////////////////////////
  251. const char* ControlUnit::swap_reg_to_mdr(int reg)
  252. {
  253.    data_path.a_sel(reg);
  254.    data_path.alu_fn(SWAP_A);
  255.    data_path.mdr_sel(ALU_BUS);
  256.    data_path.mdr_latch();
  257.    return(data_path.Clock());
  258. }
  259.  
  260. ///////////////////////////////////////////////////////////////////////////////
  261. // 0 -> reg                    
  262. ///////////////////////////////////////////////////////////////////////////////
  263. const char* ControlUnit::clr_reg(int reg)
  264. {
  265.    data_path.a_sel(reg);
  266.    data_path.b_sel(reg);
  267.    data_path.alu_fn(XOR);
  268.    data_path.alu_gt();
  269.    data_path.wrt_a();
  270.    return(data_path.Clock());
  271. }
  272.  
  273. ///////////////////////////////////////////////////////////////////////////////
  274. // 0 -> mdr                        
  275. ///////////////////////////////////////////////////////////////////////////////
  276. const char* ControlUnit::clr_mdr(void)
  277. {
  278.    data_path.a_sel(0);                     // note: use of R0 is arbitrary
  279.    data_path.b_sel(0);
  280.    data_path.alu_fn(XOR);
  281.    data_path.mdr_sel(ALU_BUS);
  282.    data_path.mdr_latch();
  283.    return(data_path.Clock());
  284. }
  285.  
  286. ///////////////////////////////////////////////////////////////////////////////
  287. // flags -> reg                  
  288. ///////////////////////////////////////////////////////////////////////////////
  289. const char* ControlUnit::flags_to_reg(int reg)
  290. {
  291.    data_path.a_sel(reg);
  292.    data_path.alu_fn(CC_OUT);
  293.    data_path.alu_gt();
  294.    data_path.wrt_a();
  295.    return(data_path.Clock());
  296. }
  297.  
  298. ///////////////////////////////////////////////////////////////////////////////
  299. // flags -> mdr                                                       
  300. ///////////////////////////////////////////////////////////////////////////////
  301. const char* ControlUnit::flags_to_mdr(void)
  302. {
  303.    data_path.alu_fn(CC_OUT);
  304.    data_path.mdr_sel(ALU_BUS);
  305.    data_path.mdr_latch();
  306.    return(data_path.Clock());
  307. }
  308.  
  309. ///////////////////////////////////////////////////////////////////////////////
  310. // reg -> flags                                                    
  311. ///////////////////////////////////////////////////////////////////////////////
  312. const char* ControlUnit::reg_to_flags(int reg)
  313. {
  314.    data_path.a_sel(reg);
  315.    data_path.alu_fn(A_CC);
  316.    return(data_path.Clock());
  317. }
  318.  
  319. ///////////////////////////////////////////////////////////////////////////////
  320. // reg_a -> reg_b (condition codes not affected)           
  321. ///////////////////////////////////////////////////////////////////////////////
  322. const char* ControlUnit::pass_reg_to_reg(int reg_a, int reg_b)
  323. {
  324.    data_path.a_sel(reg_a);
  325.    data_path.b_sel(reg_b);
  326.    data_path.alu_fn(PASS_A);
  327.    data_path.alu_gt();
  328.    data_path.wrt_b();
  329.    return(data_path.Clock());
  330. }
  331.  
  332. ///////////////////////////////////////////////////////////////////////////////
  333. // reg_s -> (reg_d); reg_d + 1 -> reg_d                               
  334. ///////////////////////////////////////////////////////////////////////////////
  335. const char* ControlUnit::reg_to_reg_indirect_with_inc(int reg_s, int reg_d)
  336. {
  337.    data_path.a_sel(reg_s);
  338.    data_path.b_sel(reg_d);
  339.    data_path.alu_fn(INC_B_NCC);
  340.    data_path.alu_gt();
  341.    data_path.wrt_b();
  342.    data_path.mdr_sel(A_BUS);
  343.    data_path.mdr_latch();
  344.    data_path.mdr_out_en();
  345.    data_path.mar_sel(B_BUS);
  346.    data_path.mar_latch();
  347.    data_path.mar_out_en();
  348.    return(data_path.Clock());
  349. }
  350.  
  351. ///////////////////////////////////////////////////////////////////////////////
  352. // mdr -> (mar); reg + 1 -> reg                                       
  353. ///////////////////////////////////////////////////////////////////////////////
  354. const char* ControlUnit::mdr_to_mar_indirect_with_inc(int reg)
  355. {
  356.    data_path.a_sel(reg);
  357.    data_path.alu_fn(INC_A_NCC);
  358.    data_path.alu_gt();
  359.    data_path.wrt_a();
  360.    data_path.mdr_out_en();
  361.    data_path.mar_out_en();
  362.    return(data_path.Clock());
  363. }
  364.  
  365. ///////////////////////////////////////////////////////////////////////////////
  366. // reg_s -> (reg_d); reg_d - 1 -> reg_d                          
  367. ///////////////////////////////////////////////////////////////////////////////
  368. const char* ControlUnit::reg_to_reg_indirect_with_dec(int reg_s, int reg_d)
  369. {
  370.    data_path.a_sel(reg_s);
  371.    data_path.b_sel(reg_d);
  372.    data_path.alu_fn(DEC_B_NCC);
  373.    data_path.alu_gt();
  374.    data_path.wrt_b();
  375.    data_path.mdr_sel(A_BUS);
  376.    data_path.mdr_latch();
  377.    data_path.mdr_out_en();
  378.    data_path.mar_sel(B_BUS);
  379.    data_path.mar_latch();
  380.    data_path.mar_out_en();
  381.    return(data_path.Clock());
  382. }
  383.  
  384.